#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
//双向链表做一个学生管理系统

//学生基本信息
typedef struct{
    int id;
    char name[33];
    int age;
}ElemType_t;

//全局变量定义班级
int classNum = 1;

//设计节点的数据类型
typedef struct node{
    ElemType_t data;
    struct node *prev;
    struct node *next;
}Node_t;

//链表的管理结构体
typedef struct list{
    Node_t* head;
    int classNum;//记录班级
    struct list * Lnext;
}List_t;

//将班级通过Lnext连接起来
void cmpClass(List_t* firstList,List_t* list){
    List_t* p =firstList;
    while(1){
        if(p->Lnext==NULL){
            p->Lnext=list;
            break;
        }
        p=p->Lnext;
    }
}

//查找是否有选择的班级并返回
List_t* findSelectClass(List_t* firstList,int num){
    List_t* p =firstList;
    while(1){
        if(p->classNum==num){
            return p;
        }
        if(p->Lnext==NULL){
            printf("你选择的班级并没有\n");
            break;
        }
        p=p->Lnext;
    }
    return NULL;

}

//初始化链表(添加班级)
List_t* initList(){
    List_t* list = (List_t*)malloc(sizeof(List_t));
    if(list==NULL){
        printf("连大头节点的空间都申请不到,玩钩子\n");
        return NULL;
    }
    list->head=NULL;
    list->classNum=classNum;
    list->Lnext=NULL;
    classNum++;

    //申请头节点内存空间
    list->head=malloc(sizeof(Node_t));
    if(list->head == NULL)
    {
        printf("没空间申请头节点\n");
        return NULL;
    }
    list->head->next=NULL;
    list->head->prev=NULL;
    return list;
}

//判断链表是否为空
bool isEmpty(List_t* list){
    return list->head->next==NULL;
}

//尾插法(添加学生)
void insertListTail(List_t* list,ElemType_t data){
    Node_t* newNode = (Node_t*)malloc(sizeof(Node_t));
    if(newNode==NULL){
        printf("连节点的空间都申请不到,玩钩子,玩不了一点\n");
        return;
    }
    newNode->next=NULL;
    newNode->prev=list->head;
    newNode->data.id=data.id;
    strcpy(newNode->data.name,data.name);
    newNode->data.age=data.age;
    if(isEmpty(list)){
        list->head->next=newNode;
        newNode->prev=list->head;
    }else{
        Node_t* p = list->head->next;
        while(1){
            if(p->next==NULL){
                p->next=newNode;
                newNode->prev=p;
                break;
            }
            p=p->next;
        }
    }
}

//头插法(添加学生)
void insertListHead(List_t* list, ElemType_t data){
    Node_t* newNode = (Node_t*)malloc(sizeof(Node_t));
    if(newNode==NULL){
        printf("连节点的空间都申请不到,玩钩子,玩不了一点\n");
        return;
    }
    newNode->next=NULL;
    newNode->prev=list->head;
    newNode->data.id=data.id;
    strcpy(newNode->data.name,data.name);
    newNode->data.age=data.age;
    if(isEmpty(list)){
        list->head->next=newNode;
        newNode->prev=list->head;
    }else{
        newNode->next=list->head->next;
        list->head->next->prev=newNode;
        list->head->next=newNode;
        newNode->prev=list->head;
    }
}

//通过学号删除节点(删除学生)
void deleteNodeById(List_t* list,int studentId){
    if(isEmpty(list)){
        printf("没有节点,删除鬼子\n");
        return;
    }
    Node_t* p = list->head->next;
    while(1){
        if(p->data.id==studentId){
            break;
        }
        if(p->next==NULL){
            printf("没有要删除的节点\n");
            return;
        }
        p=p->next;
    }
    if(list->head->next->data.id==p->data.id){
        list->head->next=p->next;
        free(p);
        list->head->next->prev=NULL;
    }else if(p->next==NULL){
        p->prev->next=NULL;
        free(p);
    }else{
        p->prev->next=p->next;
        p->next->prev=p->prev;
        free(p);
    }
}

//通过学号修改学生信息(修改学生)
void changeStudentInfo(List_t* list,int studentId){
    int chId= 0;
    char chName[33];
    int chAge= 0;
    if(isEmpty(list)){
        printf("学生都没有,你还想修改什么\n");
        return;
    }
    Node_t* p=list->head->next;
    while (1){
        if(p->data.id==studentId){
            printf("请输入修改后的学生信息\n");
            printf("请输入学号:\n");
            scanf("%d",&chId);
            printf("请输入名字:\n");
            scanf("%s",chName);
            printf("请输入年龄:\n");
            scanf("%d",&chAge);
            p->data.age=chAge;
            p->data.id=chId;
            strcpy(p->data.name,chName);
            return;
        }
        if(p->next==NULL){
            printf("没找到哦~\n");
            break;
        }
        p=p->next;
    }
    
}

//通过学号查找学生信息
void findStudentInfoById(List_t* list,int studentId){
    if(isEmpty(list)){
        printf("学生都没有,你还想查找什么\n");
        return;
    }
    Node_t* p=list->head->next;
    while (1){
        if(p->data.id==studentId){
            printf("要找的学生找到了\n");
            printf("学号\t姓名\t年龄\t\n");
            printf("%d\t%s\t%d\t\n",p->data.id,p->data.name,p->data.age);
            return;
        }
        if(p->next==NULL){
            printf("没找到要找的学生哦~\n");
            break;
        }
        p=p->next;
    }
}

//通过姓名查找学生信息
void findStudentInfoByName(List_t* list,char* pName){
    int flag = 0;
    if(isEmpty(list)){
        printf("学生都没有,你还想查找什么\n");
        return;
    }
    Node_t* p=list->head->next;
    while (1){
        if(strcmp(p->data.name,pName)==0){
            if(flag == 0){
            printf("要找的学生找到了\n");
            printf("学号\t姓名\t年龄\t\n");
            flag++;
            }
            printf("%d\t%s\t%d\t\n",p->data.id,p->data.name,p->data.age);
        }
        if(p->next==NULL){
            if(flag==0){
                printf("没找到要找的学生哦~\n");
            }
            break;
        }
        p=p->next;
    }
}

//通过年龄查找学生信息
void findStudentInfoByAge(List_t* list,int sutdentAge){
    int flag = 0;
    if(isEmpty(list)){
        printf("学生都没有,你还想查找什么\n");
        return;
    }
    Node_t* p=list->head->next;
    while (1){
        if(p->data.age==sutdentAge){
            if(flag == 0){
            printf("要找的学生找到了\n");
            printf("学号\t姓名\t年龄\t\n");
            flag++;
            }
            printf("%d\t%s\t%d\t\n",p->data.id,p->data.name,p->data.age);
        }
        if(p->next==NULL){
            if(flag==0){
                printf("没找到要找的学生哦~\n");
            }
            break;
        }
        p=p->next;
    }
}
//链表长度
int listLength(List_t* list){
    int count = 1;
    if(isEmpty(list)){
        return 0;
    }
    Node_t* p =list->head->next;
    while(1){
        if(p->next==NULL){
            return count;
        }
        p=p->next;
        count++;
    }
}

//展示链表
void showList(List_t* list){
    if(isEmpty(list)){
        printf("链表里什么都没有,你想展示什么\n");
        return;
    }
    Node_t* p = list->head->next;
    printf("学号\t姓名\t年龄\t\n");
    while (1){
        printf("%d\t%s\t%d\t\n",p->data.id,p->data.name,p->data.age);
        if(p->next==NULL){
            break;
        }
        p=p->next;
    }
    printf("\n");
}

int main(){

    printf("---------欢迎使用学生管理系统---------\n");
    int ope = 0;
    int opeTwo = 0;
    int opeThree = 0;
    int deleteStudentById = 0;
    int changeStudentById = 0;
    int findStudentById = 0;
    char findStudentByName[33] = {'0'};
    int findStudentByAge = 0;
    List_t* opeClass;
    List_t* firstClass;
    List_t* selectListClass;
    ElemType_t addStudentData;
    int selectClass = 0;
loop2:
    while(1){
        printf("[1]添加班级  [2]进入班级  [3]退出系统\n");
        printf("请输入操作\n");
        scanf("%d",&ope);
        switch (ope)
        {
        case 1:
            if(classNum==1){
                firstClass=initList();
                printf("成功添加[%d]班\n",firstClass->classNum);
            }else{
                opeClass=initList();
                printf("成功添加[%d]班\n",opeClass->classNum);
                //将班级链接起来
                cmpClass(firstClass,opeClass);
            }
            break;
        case 2:
            printf("请选择你要进入几班\n");
            scanf("%d",&selectClass);
            selectListClass=findSelectClass(firstClass,selectClass);
            if(selectListClass==NULL){
                break;
            }
            goto loop;
            break;
        case 3:
            printf("---------已退出学生管理系统---------");
            return 0;       
        default:
            break;
        }
    }
    
loop:
loop3:
    while(1){
        printf("---------你已进入[%d]班的管理系统---------\n",selectListClass->classNum);
        printf("[1]添加学生  [2]删除学生  [3]修改学生  [4]查找学生  [5]展示该班所有学生 [6]退出\n");
        printf("请输入操作\n");
        scanf("%d",&opeTwo);
        switch (opeTwo)
        {
        case 1:
            printf("请输入学生信息\n");
            printf("输入学号\n");
            scanf("%d",&addStudentData.id);
            printf("输入姓名\n");
            scanf("%s",addStudentData.name);
            printf("输入年龄\n");
            scanf("%d",&addStudentData.age);
            insertListTail(selectListClass,addStudentData);
            break;
        case 2:
            printf("现在通过学号来删除学生信息\n");
            printf("请输入学号\n");
            scanf("%d",&deleteStudentById);
            deleteNodeById(selectListClass,deleteStudentById);
            printf("学生信息已被删除\n");
            break;
        case 3:
            printf("现在通过学号来修改学生信息\n");
            printf("请输入学号\n");
            scanf("%d",&changeStudentById);
            changeStudentInfo(selectListClass,changeStudentById);
            break;
        case 4:
            goto findStu;
            break;
        case 5:
            printf("---------[%d]班所有学生信息如下---------\n",selectListClass->classNum);
            showList(selectListClass);
            printf("--------------------------------------\n");
            break;
        case 6:
            goto loop2;
            break;
        default:
            break;
        }
    }
findStu:
    while(1){
        printf("---------你已进入查找学生模块---------\n");
        printf("[1]通过学号  [2]通过姓名  [3]通过年龄  [4]退出\n");
        printf("请输入操作\n");
        scanf("%d",&opeThree);
        switch (opeThree)
        {
        case 1:
            printf("现在通过学号来查找学生信息\n");
            printf("请输入学生id\n");
            scanf("%d",&findStudentById);
            findStudentInfoById(selectListClass,findStudentById);
            break;
        case 2:
            printf("现在通过姓名来查找学生信息\n");            
            printf("请输入学生姓名\n");
            scanf("%s",findStudentByName);
            findStudentInfoByName(selectListClass,findStudentByName);
            break;
        case 3:
            printf("现在通过年龄来查找学生信息\n");
            printf("请输入学生年龄\n");
            scanf("%d",&findStudentByAge);
            findStudentInfoByAge(selectListClass,findStudentByAge);
            break;
        case 4:
            goto loop3;
            break;
        default:
            break;
        }
    }

    
}